package com.cykj.pos.service.impl;

import cn.hutool.core.lang.Console;
import com.alibaba.fastjson.JSONObject;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.cykj.common.core.domain.AjaxResult;
import com.cykj.common.core.domain.entity.SysUser;
import com.cykj.common.utils.SecurityUtils;
import com.cykj.pos.domain.*;
import com.cykj.pos.domain.dto.BizAgentidAppkeyDTO;
import com.cykj.pos.domain.dto.CashOutVO;
import com.cykj.pos.domain.dto.RiskControlDTO;
import com.cykj.pos.domain.dto.SubmitGrantDetailDTO;
import com.cykj.pos.mapper.BizPosMachineMapper;
import com.cykj.pos.mapper.FeiShunSettlementMapper;
import com.cykj.pos.payment.controller.CallbackController;
import com.cykj.pos.pojo.*;
import com.cykj.pos.service.*;
import com.cykj.pos.util.*;
import com.cykj.pos.websocket.server.WebSocketServer;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.configurationprocessor.json.JSONArray;
import org.springframework.boot.configurationprocessor.json.JSONException;
import org.springframework.stereotype.Service;
import org.springframework.util.ResourceUtils;

import java.io.File;
import java.math.BigDecimal;
import java.net.URLDecoder;
import java.net.URLEncoder;
import java.sql.Timestamp;
import java.text.SimpleDateFormat;
import java.util.*;

@Service
public class PosV1AppMerApiServiceImpl implements PosV1AppMerApiService {
    private Logger logger = LoggerFactory.getLogger(CallbackController.class);


    @Autowired
    private  IBizMerchantReceiverService iBizMerchantReceiverService;
    @Autowired
    private BizMerchantReceiverServiceImpl bizMerchantReceiverService;
    @Autowired
    private IBizMerchantService bizMerchantService;

    @Autowired
    private FeiShunSettlementMapper feiShunSettlementMapper;
    @Autowired
    private BizPosMachineMapper posMachineMapper;
    @Autowired
    private IBizWalletService walletService;
    @Autowired
    private IBizMicroInfoService bizMicroInfoService;
    @Autowired
    private IBizMicroInfoService microInfoService;
    @Autowired
    private IBizCashoutRecordsService cashoutRecordsService;
    @Autowired
    private IBizCashoutFeeService cashoutFeeService;
    @Autowired
    private WebSocketServer webSocketServer;
    @Autowired
    private IBizMerchantService merchantService;
    @Autowired
    private IBizMerchBillService merchBillService;
    @Autowired
    private  IBizWithdrawalRecordsService iBizWithdrawalRecordsService;
    @Autowired
    private  BizWithdrawalRecordsServiceImpl bizWithdrawalRecordsServiceImpl;
    /**
     * 用户签约接口(userSign)（同步接口）
     * @param
     */
    public AjaxResult userSign(BizMicroInfo bizMicroInfoByMerchId,String userId) {
        //查询部门
        String deptId = bizMicroInfoService.getDeptIdByuserId(userId);
        //根据部门查代付主体
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByDeptId(deptId);
        //获取签约信息
        BizMerchantReceiver bizMerchantReceiver1 =
                iBizMerchantReceiverService.selectBizMerchantReceiverByUserIdAndMerchId(
                        bizMicroInfoByMerchId.getMerchId().toString(),userId,deptId);
        //判断当前账户签约状态
        if(bizMerchantReceiver1!=null&&"2".equals(bizMerchantReceiver1.getContractStatus())){
            return AjaxResult.success("已签约");
        }
        BizMerchantReceiver bizMerchantReceiver_ = new BizMerchantReceiver();
        bizMerchantReceiver_.setMerchId(bizMicroInfoByMerchId.getMerchId());
        BizMerchantReceiver bizMerchantReceiver =  new BizMerchantReceiver();
        UserSign userSign = new UserSign();
        userSign.setRealName(bizMicroInfoByMerchId.getMerchIdcardName());
        userSign.setCardId(bizMicroInfoByMerchId.getMerchIdcard());
        userSign.setPhoneNo(bizMicroInfoByMerchId.getMerchBankMobile());
        bizMerchantReceiver.setMerchName(bizMicroInfoByMerchId.getMerchIdcardName());
        bizMerchantReceiver.setMerchIdcard(bizMicroInfoByMerchId.getMerchIdcard());
        bizMerchantReceiver.setMerchBankMobile(bizMicroInfoByMerchId.getMerchBankMobile());
        bizMerchantReceiver.setMerchBankCardno(bizMicroInfoByMerchId.getMerchBankCardno());
        bizMerchantReceiver.setMerchId(bizMicroInfoByMerchId.getMerchId());
        bizMerchantReceiver.setUserId(Long.valueOf(userId));
        Map<String, Object> map = HqyApiUtilsV2.callHqyMerApi(UUID.randomUUID().toString(),
                HqyMerFunctionEnumsV2.USER_SIGN.getCode(),
//                HqyApiContantsV2.HQY_MER_ID_DQHB_V2,
                bizBehalfPayment.getBehalfCode(),
                userSign,bizBehalfPayment);
        JSONObject obj =JSONObject.parseObject(map.get("result").toString());
        logger.info(map.toString());
        if(bizMerchantReceiver1!=null){
            bizMerchantReceiver.setId(bizMerchantReceiver1.getId());
        }
        if("0".equals(obj.get("businessStatus"))){
            //签约成功
            bizMerchantReceiver.setContractStatus("2");
            bizMerchantReceiver.setSign("B");
            bizMerchantReceiver.setDeptId(deptId);
            iBizMerchantReceiverService.saveOrUpdate(bizMerchantReceiver);
            return AjaxResult.success("签约成功");
        }else{
            //签约失败
            bizMerchantReceiver.setContractStatus("1");
            bizMerchantReceiver.setSign("B");
            bizMerchantReceiver.setDeptId(deptId);
            String msg = "";
            if("".equals(obj.get("explain")) || null == obj.get("explain") ){
                if("".equals(obj.get("message")) || null == obj.get("message")){
                    msg = "请联系服务商";
                }else{
                    msg = obj.get("message").toString();
                }
            }else{
                msg = obj.get("explain").toString();
            }
            bizMerchantReceiver.setErroMessage(msg);
            iBizMerchantReceiverService.saveOrUpdate(bizMerchantReceiver);
            return AjaxResult.error("签约失败,"+msg);
        }
    }

    @Override
    public String getStatus(JSONObject jsonObject) {
        return iBizMerchantReceiverService.getStatus(jsonObject.get("merchId").toString());
    }

    /**
     * 商户多账户余额查询接口(searchMer) （同步接口）
     * @param jsonObject
     * @return
     */
    @Override
    public Map<String, Object> searchMer(JSONObject jsonObject) {
        SearchMer req = new SearchMer();
        req.setJnlNo(jsonObject.get("jnlNo").toString());
        Map<String, Object> hqyResultMap = HqyApiUtilsV2.callHqyMerApi(
                UUID.randomUUID().toString(),
                HqyMerFunctionEnumsV2.SEARCH_MER.getCode(),
                req,null);
        return hqyResultMap;
    }


    /**
     * 出款接口（batchPayment）
     * @param merchId
     * @return
     */
    public AjaxResult batchPayMent(String merchId,SubmitGrantDetailDTO submitGrantDetailDTO,String dftype,String deptId) throws Exception {
        AjaxResult ajaxResult=AjaxResult.success("单笔提现");
        /*获取编码密钥*/
        BizAgentidAppkeyDTO bizAgentidAppkeyDTO= bizMerchantReceiverService.getAgentidAppkey(SecurityUtils.getLoginUser().getUser().getUserId());
        submitGrantDetailDTO.setUserId(SecurityUtils.getLoginUser().getUser().getUserId());
        /*生成  唯一值*/
        String natchno="ZF"+System.currentTimeMillis()+""+String.format("%04d",new Random().nextInt(9999));
        /*获取当前  userid的钱包key*/
        BizWallet bizWallet= posMachineMapper.selbizWallet(submitGrantDetailDTO.getUserId());
        /*解密app传过来的   加密过的金额，用来风控接口*/
        String money= DESHelperUtil.decrypt(bizWallet.getSecretKey(), submitGrantDetailDTO.getCashOutAmount());
        BigDecimal cashOutAmount = new BigDecimal(money);
        if(cashOutAmount.compareTo(new BigDecimal(20)) <= 0){
            return AjaxResult.error("单笔提现金额不得低于20元");
        }
        BizMicroInfo bizMicroInfoByMerchId = bizMicroInfoService.getBizMicroInfoByMerchId(Long.parseLong(merchId));
        /*查询签约状态  0待签约；1-签约中；2-已签约；3-失败 4-拒签*/
        BizMerchantReceiver bizMerchantReceiver= null;
        if("A".equals(dftype)){
            bizMerchantReceiver=iBizMerchantReceiverService.selectReceiverMerchIdcardIsSignLzf(bizMicroInfoByMerchId.getMerchIdcard());
        }else{
            bizMerchantReceiver=iBizMerchantReceiverService.selectReceiverMerchIdcardIsSign(bizMicroInfoByMerchId.getMerchIdcard(),dftype,deptId);
        }

        if (bizMerchantReceiver==null || !bizMerchantReceiver.getContractStatus().equals("2")){
            return AjaxResult.error("未签约或签约未成功");
        }
        // 提现预支付
        return batchPayMentData(submitGrantDetailDTO,natchno,bizMerchantReceiver,bizMicroInfoByMerchId);
//        JSONObject obj =JSONObject.parseObject(map.get("result").toString());
//        if("0".equals(obj.get("businessStatus").toString())){
//            return AjaxResult.success(obj.get("businessStatus").toString(),"受理成功",obj.get("availableBalance").toString());
//        }else{
//            return AjaxResult.error(obj.get("businessStatus").toString(),"受理失败");
//        }



//        RiskControlDTO riskControlDTO=new RiskControlDTO();
//        riskControlDTO.setIdcard(bizMicroInfoByMerchId.getMerchIdcard());
//        riskControlDTO.setInAcctName(bizMicroInfoByMerchId.getMerchIdcardName());
//        riskControlDTO.setMobile(bizMicroInfoByMerchId.getMerchBankMobile());
//        riskControlDTO.setInAcctNo(bizMicroInfoByMerchId.getMerchBankCardno());
//        riskControlDTO.setTranAmount(money);
//        /*风控接口*/
//        String token= bizMerchantReceiverService.acquireAccessToken(bizAgentidAppkeyDTO);
//        AjaxResult ajaxResultRiskControl= RiskControlUtil.getRiskControl(riskControlDTO,bizAgentidAppkeyDTO,natchno,token);
//        String code=ajaxResultRiskControl.get("code").toString();
//        String message=ajaxResultRiskControl.get("message").toString();
//        if (code.equals("0000") && message.equals("SUCCESS")){
//
//        }else {
//            return AjaxResult.error("500","系统错误");
//        }
    }


    public AjaxResult batchPayMentData(SubmitGrantDetailDTO submitGrantDetailDTO,
                                       String natchno,
                                       BizMerchantReceiver bizMerchantReceiver,
                                       BizMicroInfo bizMicroInfoByMerchId){

        AjaxResult ajaxResult = AjaxResult.success("预支付提现");
        // 账户信息
        submitGrantDetailDTO.setEncryptionCardno(0); //不加密卡号
        CashOutVO cashOutVO = microInfoService.getXinLongMerchMicroInfoByUserIdAndAccountType(submitGrantDetailDTO);
        // 提现费用信息
        BizCashoutFee cashoutFee = cashoutFeeService.getXinLongCashoutFeeByType(submitGrantDetailDTO);
        // 开始处理   判断提现金额 是否小于等于账户余额
        String key = cashOutVO.getSecretkey();// 获得key
        String secWalletAmount = cashOutVO.getWalletAmount();// 钱包总金额
        // 获得加密的金额
        String secCashOutAmount = submitGrantDetailDTO.getCashOutAmount();
        String cashOutAmountStr = DESHelperUtil.decrypt(key, secCashOutAmount);
        BigDecimal cashOutAmount = new BigDecimal(cashOutAmountStr);
        if (submitGrantDetailDTO.getAccountType() == 1) {// 结算账户提现
            String secProfitAmount = cashOutVO.getProfitAmount();//获得结算账户余额
            // 解密数据
            String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
            // 转换成BigDecimal类型
            BigDecimal profitAmount = new BigDecimal(profitAmountStr);
            if (cashOutAmount.compareTo(profitAmount) == 1) { // 大于
                return AjaxResult.error("结算账户余额不足，请重试");
            }
        } else if (submitGrantDetailDTO.getAccountType() == 2) { // 奖励账户提现
            String secRewardAmount = cashOutVO.getRewardAmount();// 获得奖励数据
            // 解密数据
            String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
            // 转换成BigDecimal类型
            BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
            if (cashOutAmount.compareTo(rewardAmount) == 1) { // 大于
                return AjaxResult.error("奖励账户余额不足，请重试");
            }
        } else if (submitGrantDetailDTO.getAccountType() == 3) { // 流量费账户提现
            String secCoverAmount = cashOutVO.getCoverAmount();// 获得奖励数据
            // 解密数据
            String coverAmountStr = DESHelperUtil.decrypt(key, secCoverAmount);
            // 转换成BigDecimal类型
            BigDecimal coverAmount = new BigDecimal(coverAmountStr);
            if (cashOutAmount.compareTo(coverAmount) == 1) { // 大于
                return AjaxResult.error("服务费账户余额不足，请重试");
            }
        } else if (submitGrantDetailDTO.getAccountType() == 4) { // 服务费账户提现
            String secFlowAmount = cashOutVO.getFlowAmount();// 获得奖励数据
            // 解密数据
            String flowAmountStr = DESHelperUtil.decrypt(key, secFlowAmount);
            // 转换成BigDecimal类型
            BigDecimal flowAmount = new BigDecimal(flowAmountStr);
            if (cashOutAmount.compareTo(flowAmount) == 1) { // 大于
                return AjaxResult.error("流量费账户余额不足，请重试");
            }
        } else {
            return AjaxResult.error("请输入accountType账户类型，1-分润账户 2-补贴账户 3-服务费账户 4-流量费费账户");
        }
        // 提现的扣费金额=服务费+费率   100-2 98
        BigDecimal serviceCharge = cashoutFee.getServiceCharge();//服务费
        //BigDecimal rate = cashoutFee.getRate();//结算账户费率
        /*if(submitGrantDetailDTO.getAccountType() == 2){
            rate = cashoutFee.getRewardRate(); //奖励账户费率
        }*/
        BigDecimal rate = cashoutFee.getRewardRate(); //奖励账户费率
        // 需要支付的手续费
        BigDecimal rateFee = cashOutAmount.multiply(rate);
        // 累计需要费用  手续费+服务费
        BigDecimal totalServiceFee = serviceCharge.add(rateFee);
        // 对服务费四舍五入
        String calcTotalServiceFee = BigDecimalUtil.getRoundString(totalServiceFee);
        // 需要支付给用户的费用
        BigDecimal paymentFee = cashOutAmount.subtract(new BigDecimal(calcTotalServiceFee));
        String orderAmt = BigDecimalUtil.getString(paymentFee);//打款金额(元)
        //--------------------------------------------

        // 钱包信息
        BizWallet wallet = walletService.getMyWalletByUserId(submitGrantDetailDTO.getUserId());
        // 钱包金额要做减法
        // 获得总金额
        String walletAmountStr = DESHelperUtil.decrypt(key, secWalletAmount);
        BigDecimal walletAmount = new BigDecimal(walletAmountStr);
        if (submitGrantDetailDTO.getAccountType() == 1) {// 结算账户提现
            String secProfitAmount = cashOutVO.getProfitAmount();//获得结算账户余额
            // 解密数据
            String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
            // 转换成BigDecimal类型
            BigDecimal profitAmount = new BigDecimal(profitAmountStr);
            // 做减法
            profitAmount = profitAmount.subtract(cashOutAmount);
            // 加密
            String profitAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(profitAmount));
            wallet.setProfitAmount(profitAmountMoneyStr);
        } else if (submitGrantDetailDTO.getAccountType() == 2) { // 奖励账户提现
            String secRewardAmount = cashOutVO.getRewardAmount();// 获得奖励数据
            // 解密数据
            String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
            // 转换成BigDecimal类型
            BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
            // 做减法
            rewardAmount = rewardAmount.subtract(cashOutAmount);
            // 加密
            String rewardAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(rewardAmount));
            wallet.setRewardAmount(rewardAmountMoneyStr);
        }else if (submitGrantDetailDTO.getAccountType() == 3) { // 服务费账户提现
            String secCoverAmount = cashOutVO.getCoverAmount();// 获得服务费数据
            // 解密数据
            String coverAmountStr = DESHelperUtil.decrypt(key, secCoverAmount);
            // 转换成BigDecimal类型
            BigDecimal coverAmount = new BigDecimal(coverAmountStr);
            // 做减法
            coverAmount = coverAmount.subtract(cashOutAmount);
            // 加密
            String coverAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(coverAmount));
            wallet.setCoverAmount(coverAmountMoneyStr);
        }else if (submitGrantDetailDTO.getAccountType() == 4) { // 流量费账户提现
            String secFlowAmount = cashOutVO.getFlowAmount();// 获得流量费数据
            // 解密数据
            String flowAmountStr = DESHelperUtil.decrypt(key, secFlowAmount);
            // 转换成BigDecimal类型
            BigDecimal flowAmount = new BigDecimal(flowAmountStr);
            // 做减法
            flowAmount = flowAmount.subtract(cashOutAmount);
            // 加密
            String flowAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(flowAmount));
            wallet.setFlowAmount(flowAmountMoneyStr);
        }

        // 钱包总额做减法
        walletAmount = walletAmount.subtract(cashOutAmount);
        // 加密钱包总额
        String walletAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(walletAmount));
        wallet.setWalletAmount(walletAmountMoneyStr);
        wallet.setSecretKey(key);
        try{
            boolean b=walletService.saveOrUpdate(wallet);
            if(!b){
                ajaxResult = AjaxResult.success("钱包扣款失败，请重新提交申请。");
                ajaxResult.put("data", false);
                return ajaxResult;
            }
        }catch (Exception e){
            ajaxResult = AjaxResult.success("钱包扣款失败，请重新提交申请。");
            ajaxResult.put("data", false);
            return ajaxResult;
        }
        // 保存钱包信息

//        BizMerchantReceiver bizMerchantReceiver = iBizMerchantReceiverService.selectBizMerchantReceiverByUserId(submitGrantDetailDTO.getUserId());
        // 生成支付记录信息
        BizCashoutRecords cashoutRecords = new BizCashoutRecords();
        cashoutRecords.setWalletId(wallet.getWalletId());// 钱包id
        cashoutRecords.setCashoutAmount(cashOutAmount);// 提现金额
        cashoutRecords.setDealAccount(bizMerchantReceiver.getMerchBankCardno());  //提现银行账户
        // cashoutRecords.setDealBank(cashOutVO.getMerchBank());  //提现所属银行
        cashoutRecords.setCashoutType(String.valueOf(submitGrantDetailDTO.getAccountType())); //提现类型 1-结算账户 2-奖励账户
        cashoutRecords.setCashoutStatus("6"); //提现状态  0  预约
        cashoutRecords.setCreateBy(submitGrantDetailDTO.getUserId());//提现人
        /*cashoutRecords.setVar1(custBatchNo); // 商户批次号
        cashoutRecords.setVar2(orderNo); //订单号*/
        cashoutRecords.setVar3(String.valueOf(serviceCharge));// 服务费
        cashoutRecords.setVar4(BigDecimalUtil.getRoundString(rateFee));// 扣费率费用
        cashoutRecords.setVar5(String.valueOf(walletAmount));// 账户余额
        cashoutRecordsService.save(cashoutRecords); // 保存

        /******************调用接口*************************/
        BatchPayment req = new BatchPayment();
        req.setBatchNo(natchno);
        //1.安阳趣蜂（平安） 2022091315575374341
        //2.池州零点（平安） 2022102416352767364
        //3.上饶市卓为网络科技有限公司   30209967602294
        //查询部门
        String  batchNo = null;
        String deptId = bizMicroInfoService.getDeptIdByuserId(submitGrantDetailDTO.getUserId().toString());
        if("117".equals(deptId)){
            batchNo = cashoutRecordsService.getPathNoEnableLzf();
        }else{
            batchNo = cashoutRecordsService.getPathNoEnable();
        }
        //获取数据库 enable为1 的可用数据

        logger.info("新代付提现   batchNo:  "+batchNo);
        req.setPathNo(batchNo);
        req.setTotalAmount(orderAmt);
        req.setTotalNum("1");
        List<BatchPaymentList> list = new ArrayList<>();
        BatchPaymentList order = new BatchPaymentList();
        order.setOrderId(IdGen.uuid());
        order.setCardId(bizMicroInfoByMerchId.getMerchIdcard());
        order.setCardNo(bizMicroInfoByMerchId.getMerchBankCardno());
        order.setPayAmount(orderAmt);
        order.setPhoneNo(bizMicroInfoByMerchId.getMerchBankMobile());
        order.setRealName(bizMicroInfoByMerchId.getMerchIdcardName());
        list.add(order);
        req.setPayInfos(list);

        //根据部分查代付主体
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByDeptId(deptId);
        Map<String, Object> hqyResultMap = HqyApiUtilsV2.callHqyMerApi(UUID.randomUUID().toString(), HqyMerFunctionEnumsV2.BATCH_PAYMENT.getCode(), req,bizBehalfPayment);
        JSONObject obj =JSONObject.parseObject(hqyResultMap.get("result").toString());
        if("0".equals(obj.getString("businessStatus"))){//受理成功
            String prepaymentMess = "预约提现成功：提现金额：" + cashOutAmount + "元，手续费" + calcTotalServiceFee + "元，实际到账金额为："
                    + orderAmt + "元，账户余额为：" + walletAmount + "元。";
            System.out.println(prepaymentMess);
            BizMessageRecords prepaymentMessageRecords = new BizMessageRecords();
            prepaymentMessageRecords.setMsgContent(prepaymentMess);// 消息内容
            prepaymentMessageRecords.setMsgType(3); // 消息类型  3
            prepaymentMessageRecords.setReadStatus(0); // 消息未读
            prepaymentMessageRecords.setAdviceType(1); // 业务消息
            webSocketServer.sendInfo(submitGrantDetailDTO.getUserId(), prepaymentMessageRecords);// 发送消息
            /*// 获得请求流水号 reqNo
            String reqNo = object.getString("deal_no");
            // 获得企业系统内部订单号 outOrderNo
            String outOrderNo = object.getString("deal_no");*/
            cashoutRecords.setVar1(natchno); // 商户批次号修改为企业系统内部订单号
            cashoutRecords.setVar2(natchno); // 订单号修改为请求流水号
            cashoutRecords.setIsRefund("0"); //是否退款
            cashoutRecordsService.saveOrUpdate(cashoutRecords); // 重新保存一下
            ajaxResult = AjaxResult.success("支付成功，请关注回调接口。");
            ajaxResult.put("data", true);
            return ajaxResult;
        }else{
            if("117".equals(deptId)){
                FeiShunSettlement feiShunSettlement =new FeiShunSettlement();
                feiShunSettlement.setBankName(bizMicroInfoByMerchId.getMerchBank());//开户行
                feiShunSettlement.setBankNum(bizMicroInfoByMerchId.getMerchBankCardno());//申请人账号
                feiShunSettlement.setSettleAccount(orderAmt);//结算金额
                feiShunSettlement.setUserName(bizMicroInfoByMerchId.getMerchIdcardName());//申请人名称
                feiShunSettlement.setUserNum(bizMicroInfoByMerchId.getMerchIdcard());//申请人身份证号
                feiShunSettlement.setUserTel(bizMicroInfoByMerchId.getMerchBankMobile());//电话
                feiShunSettlement.setOrderNo(natchno);
                feiShunSettlement.setCreteDate(DateUtils.dateFormatString(new Date()));
                feiShunSettlement.setStatus("10");//挂起状态
                feiShunSettlementMapper.insert(feiShunSettlement);
                // 发消息
                String prepaymentMess = "预约提现成功：提现金额：" + cashOutAmount + "元，手续费" + calcTotalServiceFee + "元，实际到账金额为："
                        + orderAmt + "元，账户余额为：" + walletAmount + "元。";
                System.out.println(prepaymentMess);
                BizMessageRecords prepaymentMessageRecords = new BizMessageRecords();
                prepaymentMessageRecords.setMsgContent(prepaymentMess);// 消息内容
                prepaymentMessageRecords.setMsgType(3); // 消息类型  3
                prepaymentMessageRecords.setReadStatus(0); // 消息未读
                prepaymentMessageRecords.setAdviceType(1); // 业务消息
                webSocketServer.sendInfo(submitGrantDetailDTO.getUserId(), prepaymentMessageRecords);// 发送消息
                cashoutRecords.setVar1(natchno); // 商户批次号修改为企业系统内部订单号
                cashoutRecords.setVar2(natchno); // 订单号修改为请求流水号
                cashoutRecords.setIsRefund("0"); // 订单号修改为请求流水号
                cashoutRecordsService.saveOrUpdate(cashoutRecords); // 重新保存一下
                ajaxResult = AjaxResult.success("支付成功，请关注回调接口。");
                ajaxResult.put("data", true);
                return ajaxResult;
            }else{
                // 回退
                String call_result = prepaymentCallBack(cashoutRecords, obj.getString("explain"));
                System.out.println(call_result);
                ajaxResult = AjaxResult.success("支付失败。");
                ajaxResult.put("data", false);
                return ajaxResult;
            }
        }
    }

    // 预支付回退
    private String prepaymentCallBack(BizCashoutRecords cashoutRecords, String msg) {
        // 钱退回
        BizWallet wallet = walletService.getMyWalletByUserId(cashoutRecords.getCreateBy());
        String secProfitAmount = wallet.getProfitAmount();//获得结算账户余额
        String secRewardAmount = wallet.getRewardAmount();// 获得奖励数据
        String key = wallet.getSecretKey();// 获得key
        // 解密数据
        String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
        String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
        // 转换成BigDecimal类型
        BigDecimal profitAmount = new BigDecimal(profitAmountStr);
        BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
        // 预支付出去的金额为
        BigDecimal paymentMoney = cashoutRecords.getCashoutAmount();
        // 根据cashout_type  提现类型 1-结算账户 2-奖励账户
        String cashoutType = cashoutRecords.getCashoutType();
        if ("1".equals(cashoutType)) {//1-结算账户
            profitAmount = profitAmount.add(paymentMoney);
        } else if ("2".equals(cashoutType)) {//2-奖励账户
            rewardAmount = rewardAmount.add(paymentMoney);
        } else {
            return "success";
        }
        BigDecimal walletAmount = profitAmount.add(rewardAmount);
        // 加密
        String profitAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(profitAmount));
        String rewardAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(rewardAmount));
        String walletAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(walletAmount));
        wallet.setProfitAmount(profitAmountMoneyStr);
        wallet.setRewardAmount(rewardAmountMoneyStr);
        wallet.setWalletAmount(walletAmountMoneyStr);
        wallet.setSecretKey(key);
        // 保存钱包信息
        walletService.saveOrUpdate(wallet);
        // 发消息
        String paymentFailMess = "您的预支付提现失败，提现金额" + cashoutRecords.getCashoutAmount() + "元已经返回您的余额请注意查收，失败原因：" + msg;
        System.out.println(paymentFailMess);
        BizMessageRecords paymentFailMessageRecords = new BizMessageRecords();
        paymentFailMessageRecords.setMsgContent(paymentFailMess);// 消息内容
        paymentFailMessageRecords.setMsgType(5); // 消息类型  5
        paymentFailMessageRecords.setReadStatus(0); // 消息未读
        paymentFailMessageRecords.setAdviceType(1); // 业务消息
        webSocketServer.sendInfo(cashoutRecords.getCreateBy(), paymentFailMessageRecords);// 发送消息
        // 提现记录  更新状态为 0  失败
        cashoutRecords.setCashoutStatus("0");
        cashoutRecords.setMsgId(paymentFailMessageRecords.getMsgId()); // 存储记录中对应的消息id
        cashoutRecords.setErrorMsg(msg);// 存储失败原因
        cashoutRecordsService.saveOrUpdate(cashoutRecords);
        return "call_back_success";
    }



    /**
     * 单笔出款结果查询接口（queryPayment）
     * @param jsonObject
     * @return
     */
    @Override
    public AjaxResult queryPayment(JSONObject jsonObject) {
        QueryPayment req = new QueryPayment();
        req.setBatchNo(jsonObject.get("batchNo").toString());
        req.setOrderId(jsonObject.get("orderId").toString());
        Map<String, Object> hqyResultMap = HqyApiUtilsV2.callHqyMerApi(
                UUID.randomUUID().toString(),
                HqyMerFunctionEnumsV2.QUERY_PAYMENT.getCode(),
                req,null);
        logger.info("hqyResultMap->{}", hqyResultMap);
        JSONObject obj =JSONObject.parseObject(hqyResultMap.get("result").toString());

        if("0000".equals(obj.getString("resultCode"))){

            //返回成功
            String batchNo = obj.getString("batchNo");
            String orderId = obj.getString("orderId");//子订单号
            BizCashoutRecords cashoutRecords = cashoutRecordsService.getCashoutDataByBatchId(jsonObject.get("batchNo").toString());
            String msg = "请求中";
            if("0".equals(obj.get("remitResult"))){//交易成功
                cashoutRecords.setCashoutStatus("1");
                msg = "交易成功";
            }else if("1".equals(obj.getString("remitResult"))){//交易失败
                cashoutRecords.setCashoutStatus("0");
                msg = "交易失败";
            }else if("2".equals(obj.getString("remitResult"))){//处理中
                return  AjaxResult.error("wait", "提现处理中");
            }
            cashoutRecords.setVar2(orderId);
            cashoutRecords.setIsRefund("0");
            cashoutRecordsService.saveOrUpdate(cashoutRecords);
            return AjaxResult.error("请求成功", msg);
        }else{
            return AjaxResult.error("请求失败", obj.getString("resultMsg"));
        }
    }

    @Override
    public String notifyPayment(String requestJson,String code) throws Exception {
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByCode(code);
        org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj
                = new org.springframework.boot.configurationprocessor.json.JSONObject(requestJson);
//        String reqMsgId = requestJsonObj.getString("reqMsgId");
        String headStr = requestJsonObj.getString("head");
        headStr = URLDecoder.decode(headStr, "UTF-8");
        String cipherStr = requestJsonObj.getString("cipher");
        String bodyStr = requestJsonObj.getString("body");
        String signStr = requestJsonObj.getString("sign");
//        String hqyKey = HqyApiContantsV2.HQY_MER_KEY_V2;
        String hqyKey = bizBehalfPayment.getBehalfKey();
        String callBackState = "FAILURE";
        if (StringUtils.isNotBlank(bodyStr)) {
            headStr = URLEncoder.encode(headStr, "UTF-8");
            String cipherRes = Md5Util.getMd5(headStr + "#" + bodyStr, hqyKey, "UTF-8").toUpperCase();
            if (!cipherRes.equalsIgnoreCase(cipherStr)) {
                return "FAILURE";
            }
            //商户模式
//            File pubPlatKeyFile = ResourceUtils.getFile(HqyApiContantsV2.HQY_MER_PUBLIC_KEY_PATH_V2);
            File pubPlatKeyFile = ResourceUtils.getFile(bizBehalfPayment.getBehalfPublicKey());
            if (!RSAPemCoder.verify(bodyStr.getBytes(), RSAPemCoder.getPublicKeyFromPem(pubPlatKeyFile), signStr)) {
                return "FAILURE";
            }
            // body AES解密
            String srcResBody = AESUtilApi.decrypt(bodyStr, hqyKey);
            srcResBody = URLDecoder.decode(srcResBody, "UTF-8");
            org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj_
                    = new org.springframework.boot.configurationprocessor.json.JSONObject(srcResBody);
            System.out.println("srcResBody ==" + srcResBody);
            String batchNo = requestJsonObj_.getString("batchNo");
//            String totalSuccessNum = requestJsonObj_.getString("totalSuccessNum");
//            String totalSuccessAmt = requestJsonObj_.getString("totalSuccessAmt");
//            String totalFailNum = requestJsonObj_.getString("totalFailNum");
//            String totalFailAmt = requestJsonObj_.getString("totalFailAmt");
//            String totalNum = requestJsonObj_.getString("totalNum");
//            String totalAmt = requestJsonObj_.getString("totalAmt");
            String paymentBatchDetailInfoList = requestJsonObj_.getString("paymentBatchDetailInfoList");
//            org.springframework.boot.configurationprocessor.json.JSONOArray  requestJsonObjs
//                    = new org.springframework.boot.configurationprocessor.json.JSONObject(paymentBatchDetailInfoList);
            JSONArray requestJsonObjs = new JSONArray(paymentBatchDetailInfoList);
//            String orderId = requestJsonObjs.getJSONObject(0).getString("orderId");
            String remitResult = requestJsonObjs.getJSONObject(0).getString("remitResult");
            String remitResultMsg = requestJsonObjs.getJSONObject(0).getString("remitResultMsg");
//            String paymentAmount = requestJsonObjs.getJSONObject(0).getString("paymentAmount");
//            String successTime = requestJsonObjs.getJSONObject(0).getString("successTime");
            BizCashoutRecords cashoutRecords =
                    cashoutRecordsService.getCashoutRecordsByCustOrderNo(batchNo);
            Long userId = cashoutRecords.getCreateBy();
            if("S".equals(remitResult)){
                System.out.println("------------------------支付成功----------------------------");
                // 成功 // 发消息
                String var3 = cashoutRecords.getVar3();
                String var4 = cashoutRecords.getVar4();
                BigDecimal serviceFee = new BigDecimal(var3);
                BigDecimal rateFee = new BigDecimal(var4);
                BigDecimal totalServiceFee = serviceFee.add(rateFee);
                BigDecimal orderAmt = cashoutRecords.getCashoutAmount().subtract(totalServiceFee);
                String walletAmount = cashoutRecords.getVar5();
                String paymentMess = "您的提现已成功到账，提现金额：" + cashoutRecords.getCashoutAmount() + "元，实际到账金额为："
                        + orderAmt + "元，账户余额为：" + walletAmount + "元。提现到" + cashoutRecords.getDealBank() +
                        ",提现订单号是：" + cashoutRecords.getVar2();
                System.out.println(paymentMess);
                BizMessageRecords paymentMessageRecords = new BizMessageRecords();
                paymentMessageRecords.setMsgContent(paymentMess);// 消息内容
                paymentMessageRecords.setMsgType(4); // 消息类型  4
                paymentMessageRecords.setReadStatus(0); // 消息未读
                paymentMessageRecords.setAdviceType(1); // 业务消息
                webSocketServer.sendInfo(userId, paymentMessageRecords);// 发送消息
                // 生账单
                BizMerchBill merchBill = new BizMerchBill();
                BizMerchant merchant = merchantService.getMerchantByUserId(userId); //商户信息
                merchBill.setMerchId(merchant.getMerchId());// 商户id
                merchBill.setMerchName(merchant.getMerchName());// 商户名称
                merchBill.setBillType("4");// 款项类型 1-返现 2-分润 3-奖励 4-提现 5-押金
                Date date = cashoutRecords.getCreateTime();
                SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
                merchBill.setBillDate(sdf.format(date)); //账单日期  与提现日期一致
                merchBill.setCashoutRecordsId(cashoutRecords.getCashoutId());// 提现id
                merchBill.setAmount(cashoutRecords.getCashoutAmount().negate()); // 提现存的是负值
                merchBillService.save(merchBill); // 存账单数据
                // 提现记录  更新状态为 1
                cashoutRecords.setCashoutStatus("1");
                cashoutRecords.setVar1(batchNo);
                cashoutRecords.setMsgId(paymentMessageRecords.getMsgId()); // 存储记录中对应的消息id
                cashoutRecordsService.saveOrUpdate(cashoutRecords);
                //返上级税差
                try {
                    this.with(merchant,cashoutRecords);
                }catch (Exception e){
                    System.out.println("返上级税差异常，错误信息如下");
                    e.printStackTrace();
                }
                callBackState = "success";
            }else if("F".equals(remitResultMsg)){
                if (cashoutRecords.getIsRefund().equals("0")){
                    BizWallet wallet = walletService.getMyWalletByUserId(userId);
                    String secProfitAmount = wallet.getProfitAmount();//获得结算账户余额
                    String secRewardAmount = wallet.getRewardAmount();// 获得奖励数据
                    String secCoverAmount = wallet.getCoverAmount();// 获得服务费数据
                    String secFlowAmount = wallet.getFlowAmount();// 获得流量费数据
                    String key = wallet.getSecretKey();// 获得key
                    // 解密数据
                    String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
                    String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
                    String coverAmountStr = DESHelperUtil.decrypt(key, secCoverAmount);
                    String flowAmountStr = DESHelperUtil.decrypt(key, secFlowAmount);
                    // 转换成BigDecimal类型
                    BigDecimal profitAmount = new BigDecimal(profitAmountStr);
                    BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
                    BigDecimal coverAmount = new BigDecimal(coverAmountStr);
                    BigDecimal flowAmount = new BigDecimal(flowAmountStr);
                    // 预支付出去的金额为
                    BigDecimal paymentMoney = cashoutRecords.getCashoutAmount();
                    // 根据cashout_type  提现类型 1-结算账户 2-奖励账户
                    String cashoutType = cashoutRecords.getCashoutType();
                    if ("1".equals(cashoutType)) {//1-结算账户
                        profitAmount = profitAmount.add(paymentMoney);
                    } else if ("2".equals(cashoutType)) {//2-奖励账户
                        rewardAmount = rewardAmount.add(paymentMoney);
                    }else if ("3".equals(cashoutType)) {//2-服务费账户
                        coverAmount = coverAmount.add(paymentMoney);
                    }else if ("4".equals(cashoutType)) {//2-流量费账户
                        flowAmount = flowAmount.add(paymentMoney);
                    }
                    BigDecimal walletAmount = profitAmount.add(rewardAmount).add(coverAmount).add(flowAmount);
                    // 加密
                    String profitAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(profitAmount));
                    String rewardAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(rewardAmount));
                    String  coverAmountMoneyStr= DESHelperUtil.encrypt(key, BigDecimalUtil.getString(coverAmount));
                    String flowAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(flowAmount));
                    String walletAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(walletAmount));
                    wallet.setProfitAmount(profitAmountMoneyStr);
                    wallet.setRewardAmount(rewardAmountMoneyStr);
                    wallet.setCoverAmount(coverAmountMoneyStr);
                    wallet.setFlowAmount(flowAmountMoneyStr);
                    wallet.setWalletAmount(walletAmountMoneyStr);
                    wallet.setSecretKey(key);
                    // 保存钱包信息
                    walletService.saveOrUpdate(wallet);
                    // 发消息
                    String paymentFailMess = "您的提现失败，提现金额" + cashoutRecords.getCashoutAmount() + "元已经返回您的余额请注意查收，提现订单号" +
                            cashoutRecords.getVar2() + "，失败原因：交易失败" +"---错误信息："+remitResultMsg;
                    System.out.println(paymentFailMess);
                    BizMessageRecords paymentFailMessageRecords = new BizMessageRecords();
                    paymentFailMessageRecords.setMsgContent(paymentFailMess);// 消息内容
                    paymentFailMessageRecords.setMsgType(5); // 消息类型  5
                    paymentFailMessageRecords.setReadStatus(0); // 消息未读
                    paymentFailMessageRecords.setAdviceType(1); // 业务消息
                    webSocketServer.sendInfo(userId, paymentFailMessageRecords);// 发送消息
                    // 提现记录  更新状态为 0  失败
                    cashoutRecords.setCashoutStatus("0");
                    cashoutRecords.setMsgId(paymentFailMessageRecords.getMsgId()); // 存储记录中对应的消息id
                    cashoutRecords.setErrorMsg("---错误信息："+remitResultMsg);// 存储失败原因
                    cashoutRecords.setIsRefund("1");
                    cashoutRecordsService.saveOrUpdate(cashoutRecords);
                }
            }
        }
            return callBackState;
    }

    @Override
    public String notifyPaymentHb(String requestJson,String code) throws Exception {
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByCode(code);
        org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj
                = new org.springframework.boot.configurationprocessor.json.JSONObject(requestJson);
//        String reqMsgId = requestJsonObj.getString("reqMsgId");
        String headStr = requestJsonObj.getString("head");
        headStr = URLDecoder.decode(headStr, "UTF-8");
        String cipherStr = requestJsonObj.getString("cipher");
        String bodyStr = requestJsonObj.getString("body");
        String signStr = requestJsonObj.getString("sign");
//        String hqyKey = HqyApiContantsV2.HQY_MER_KEY_V2;
        String hqyKey = bizBehalfPayment.getBehalfKey();
        String callBackState = "FAILURE";
        if (StringUtils.isNotBlank(bodyStr)) {
            headStr = URLEncoder.encode(headStr, "UTF-8");
            String cipherRes = Md5Util.getMd5(headStr + "#" + bodyStr, hqyKey, "UTF-8").toUpperCase();
            if (!cipherRes.equalsIgnoreCase(cipherStr)) {
                return "FAILURE";
            }
            //商户模式
//            File pubPlatKeyFile = ResourceUtils.getFile(HqyApiContantsV2.HQY_MER_PUBLIC_KEY_PATH_V2);
            File pubPlatKeyFile = ResourceUtils.getFile(bizBehalfPayment.getBehalfPublicKey());
            if (!RSAPemCoder.verify(bodyStr.getBytes(), RSAPemCoder.getPublicKeyFromPem(pubPlatKeyFile), signStr)) {
                return "FAILURE";
            }
            // body AES解密
            String srcResBody = AESUtilApi.decrypt(bodyStr, hqyKey);
            srcResBody = URLDecoder.decode(srcResBody, "UTF-8");
            org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj_
                    = new org.springframework.boot.configurationprocessor.json.JSONObject(srcResBody);
            System.out.println("srcResBody ==" + srcResBody);
            String batchNo = requestJsonObj_.getString("batchNo");
//            String totalSuccessNum = requestJsonObj_.getString("totalSuccessNum");
//            String totalSuccessAmt = requestJsonObj_.getString("totalSuccessAmt");
//            String totalFailNum = requestJsonObj_.getString("totalFailNum");
//            String totalFailAmt = requestJsonObj_.getString("totalFailAmt");
//            String totalNum = requestJsonObj_.getString("totalNum");
//            String totalAmt = requestJsonObj_.getString("totalAmt");
            String paymentBatchDetailInfoList = requestJsonObj_.getString("paymentBatchDetailInfoList");
//            org.springframework.boot.configurationprocessor.json.JSONOArray  requestJsonObjs
//                    = new org.springframework.boot.configurationprocessor.json.JSONObject(paymentBatchDetailInfoList);
            JSONArray requestJsonObjs = new JSONArray(paymentBatchDetailInfoList);
//            String orderId = requestJsonObjs.getJSONObject(0).getString("orderId");
            String remitResult = requestJsonObjs.getJSONObject(0).getString("remitResult");
            String remitResultMsg = requestJsonObjs.getJSONObject(0).getString("remitResultMsg");
//            String paymentAmount = requestJsonObjs.getJSONObject(0).getString("paymentAmount");
//            String successTime = requestJsonObjs.getJSONObject(0).getString("successTime");
//            BizCashoutRecords cashoutRecords =
//                    cashoutRecordsService.getCashoutRecordsByCustOrderNo(batchNo);
//            Long userId = cashoutRecords.getCreateBy();
            LambdaQueryWrapper<BizWithdrawalRecords> lambdaQueryWrapper =  Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(BizWithdrawalRecords::getOrderNo,batchNo);
            BizWithdrawalRecords one = iBizWithdrawalRecordsService.getOne(lambdaQueryWrapper);
            if(one == null){
                Console.log(batchNo,"未查到提现记录");
                return "success";
            }
            Console.log("订单号",batchNo,"回调结果",remitResult);
            if("S".equals(remitResult)){
                System.out.println(batchNo+"------------------------支付成功----------------------------");
                // 获得提现记录 通过orderNo
                one.setPayStatus("1");//成功
                iBizWithdrawalRecordsService.saveOrUpdate(one);
                // 提现分润
                System.out.println(batchNo+"------------------------分润开始----------------------------");
                bizWithdrawalRecordsServiceImpl.executeMerchantWallet(one);
                System.out.println(batchNo+"------------------------分润结束----------------------------");
                callBackState = "success";
            }else if("F".equals(remitResult)){
                System.out.println("------------------------支付失败----------------------------");
                if("3".equals(one.getPayStatus())){// 进行中
                    one.setPayStatus("2");//已退回
                    one.setRemark(one.getRemark()+remitResultMsg);
                    System.out.println(batchNo+"------------------------保存状态开始----------------------------");
                    iBizWithdrawalRecordsService.saveOrUpdate(one);
                    System.out.println(batchNo+"------------------------保存状态结束----------------------------");
                    System.out.println(batchNo+"------------------------退回钱包开始----------------------------");
                    // 退回钱包
                    iBizWithdrawalRecordsService.refundWithdrawal(one);
                    System.out.println(batchNo+"------------------------退回钱包结束----------------------------");
                }
                callBackState = "success";
            }
        }
            return callBackState;
    }

    @Override
    public String notifyPaymentLf(String requestJson,String code) throws Exception {
        BizBehalfPayment bizBehalfPayment = bizMicroInfoService.getBehalfPaymentByCode(code);
        org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj
                = new org.springframework.boot.configurationprocessor.json.JSONObject(requestJson);
//        String reqMsgId = requestJsonObj.getString("reqMsgId");
        String headStr = requestJsonObj.getString("head");
        headStr = URLDecoder.decode(headStr, "UTF-8");
        String cipherStr = requestJsonObj.getString("cipher");
        String bodyStr = requestJsonObj.getString("body");
        String signStr = requestJsonObj.getString("sign");
//        String hqyKey = HqyApiContantsV2.HQY_MER_KEY_V2;
        String hqyKey = bizBehalfPayment.getBehalfKey();
        String callBackState = "FAILURE";
        if (StringUtils.isNotBlank(bodyStr)) {
            headStr = URLEncoder.encode(headStr, "UTF-8");
            String cipherRes = Md5Util.getMd5(headStr + "#" + bodyStr, hqyKey, "UTF-8").toUpperCase();
            if (!cipherRes.equalsIgnoreCase(cipherStr)) {
                return "FAILURE";
            }
            //商户模式
//            File pubPlatKeyFile = ResourceUtils.getFile(HqyApiContantsV2.HQY_MER_PUBLIC_KEY_PATH_V2);
            File pubPlatKeyFile = ResourceUtils.getFile(bizBehalfPayment.getBehalfPublicKey());
            if (!RSAPemCoder.verify(bodyStr.getBytes(), RSAPemCoder.getPublicKeyFromPem(pubPlatKeyFile), signStr)) {
                return "FAILURE";
            }
            // body AES解密
            String srcResBody = AESUtilApi.decrypt(bodyStr, hqyKey);
            srcResBody = URLDecoder.decode(srcResBody, "UTF-8");
            org.springframework.boot.configurationprocessor.json.JSONObject  requestJsonObj_
                    = new org.springframework.boot.configurationprocessor.json.JSONObject(srcResBody);
            System.out.println("srcResBody ==" + srcResBody);
            String batchNo = requestJsonObj_.getString("batchNo");
//            String totalSuccessNum = requestJsonObj_.getString("totalSuccessNum");
//            String totalSuccessAmt = requestJsonObj_.getString("totalSuccessAmt");
//            String totalFailNum = requestJsonObj_.getString("totalFailNum");
//            String totalFailAmt = requestJsonObj_.getString("totalFailAmt");
//            String totalNum = requestJsonObj_.getString("totalNum");
//            String totalAmt = requestJsonObj_.getString("totalAmt");
            String paymentBatchDetailInfoList = requestJsonObj_.getString("paymentBatchDetailInfoList");
//            org.springframework.boot.configurationprocessor.json.JSONOArray  requestJsonObjs
//                    = new org.springframework.boot.configurationprocessor.json.JSONObject(paymentBatchDetailInfoList);
            JSONArray requestJsonObjs = new JSONArray(paymentBatchDetailInfoList);
//            String orderId = requestJsonObjs.getJSONObject(0).getString("orderId");
            String remitResult = requestJsonObjs.getJSONObject(0).getString("remitResult");
            String remitResultMsg = requestJsonObjs.getJSONObject(0).getString("remitResultMsg");
//            String paymentAmount = requestJsonObjs.getJSONObject(0).getString("paymentAmount");
//            String successTime = requestJsonObjs.getJSONObject(0).getString("successTime");
//            BizCashoutRecords cashoutRecords =
//                    cashoutRecordsService.getCashoutRecordsByCustOrderNo(batchNo);
//            Long userId = cashoutRecords.getCreateBy();
            LambdaQueryWrapper<BizWithdrawalRecords> lambdaQueryWrapper =  Wrappers.lambdaQuery();
            lambdaQueryWrapper.eq(BizWithdrawalRecords::getOrderNo,batchNo);
            BizWithdrawalRecords one = iBizWithdrawalRecordsService.getOne(lambdaQueryWrapper);
            if(one == null){
                Console.log(batchNo,"未查到提现记录");
                return "success";
            }
            Console.log("订单号",batchNo,"回调结果",remitResult);
            if("S".equals(remitResult)){
                System.out.println(batchNo+"------------------------支付成功----------------------------");
                // 获得提现记录 通过orderNo
                one.setPayStatus("1");//成功
                iBizWithdrawalRecordsService.saveOrUpdate(one);
                // 提现分润
                System.out.println(batchNo+"------------------------分润开始----------------------------");
                bizWithdrawalRecordsServiceImpl.executeMerchantWallet(one);
                System.out.println(batchNo+"------------------------分润结束----------------------------");
                callBackState = "success";
            }else if("F".equals(remitResult)){
                System.out.println("------------------------支付失败----------------------------");
                if("3".equals(one.getPayStatus())){// 进行中
                    one.setPayStatus("2");//已退回
                    one.setRemark(one.getRemark()+remitResultMsg);
                    System.out.println(batchNo+"------------------------保存状态开始----------------------------");
                    iBizWithdrawalRecordsService.saveOrUpdate(one);
                    System.out.println(batchNo+"------------------------保存状态结束----------------------------");
                    System.out.println(batchNo+"------------------------退回钱包开始----------------------------");
                    // 退回钱包
                    iBizWithdrawalRecordsService.refundWithdrawal(one);
                    System.out.println(batchNo+"------------------------退回钱包结束----------------------------");
                }
                callBackState = "success";
            }
        }
            return callBackState;
    }

    public void with(BizMerchant merchant, BizCashoutRecords cashoutRecords) {
        if(merchant.getParentId()==0){
            return;
        }
        SysUser user=posMachineMapper.getUserByUserId(merchant.getUserId());
        BizMerchant merchant1=posMachineMapper.getMerchantByMerchId(merchant.getParentId());
        SysUser parentUser=posMachineMapper.getUserByUserId(merchant1.getUserId());
        BizWallet wallet = walletService.getMyWalletByUserId(parentUser.getUserId());
        // 预支付出去的金额为
        BigDecimal paymentMoney = cashoutRecords.getCashoutAmount();
        System.out.println(parentUser.getRate()+"    "+user.getRate());
        if(parentUser.getRate().compareTo(user.getRate())<0){
            paymentMoney=paymentMoney.multiply(user.getRate().subtract(parentUser.getRate())).setScale(2,BigDecimal.ROUND_DOWN);
            String secProfitAmount = wallet.getProfitAmount();//获得结算账户余额
            String secRewardAmount = wallet.getRewardAmount();// 获得奖励数据
            String secCoverAmount = wallet.getCoverAmount();// 获得服务费数据
            String secFlowAmount = wallet.getFlowAmount();// 获得流量费数据
            String key = wallet.getSecretKey();// 获得key
            // 解密数据
            String profitAmountStr = DESHelperUtil.decrypt(key, secProfitAmount);
            String rewardAmountStr = DESHelperUtil.decrypt(key, secRewardAmount);
            String coverAmountStr = DESHelperUtil.decrypt(key, secCoverAmount);
            String flowAmountStr = DESHelperUtil.decrypt(key, secFlowAmount);
            // 转换成BigDecimal类型
            BigDecimal profitAmount = new BigDecimal(profitAmountStr);
            BigDecimal rewardAmount = new BigDecimal(rewardAmountStr);
            BigDecimal coverAmount = new BigDecimal(coverAmountStr);
            BigDecimal flowAmount = new BigDecimal(flowAmountStr);

            // 根据cashout_type  提现类型 1-结算账户 2-奖励账户
            String cashoutType = cashoutRecords.getCashoutType();
            if ("1".equals(cashoutType)) {//1-结算账户
                profitAmount = profitAmount.add(paymentMoney);
            } else if ("2".equals(cashoutType)) {//2-奖励账户
                rewardAmount = rewardAmount.add(paymentMoney);
            }else if ("3".equals(cashoutType)) {//2-服务费账户
                coverAmount = coverAmount.add(paymentMoney);
            }else if ("4".equals(cashoutType)) {//2-流量费账户
                flowAmount = flowAmount.add(paymentMoney);
            }
            BigDecimal walletAmount = profitAmount.add(rewardAmount).add(coverAmount).add(flowAmount);
            // 生账单
            BizMerchBill merchBill = new BizMerchBill();
            merchBill.setMerchId(merchant1.getMerchId());// 商户id
            merchBill.setMerchName(merchant1.getMerchName());// 商户名称
            merchBill.setBillType("4");// 款项类型 1-返现 2-分润 3-奖励 4-提现 5-押金
            Date date = cashoutRecords.getCreateTime();
            SimpleDateFormat sdf = new SimpleDateFormat("yyyy-MM-dd HH:mm:ss");
            merchBill.setBillDate(sdf.format(date)); //账单日期  与提现日期一致
            merchBill.setCashoutRecordsId(cashoutRecords.getCashoutId());// 提现id
            merchBill.setAmount(paymentMoney); // 返税金额
            merchBillService.saveOrUpdate(merchBill); // 存账单数据
            // 加密
            String profitAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(profitAmount));
            String rewardAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(rewardAmount));
            String  coverAmountMoneyStr= DESHelperUtil.encrypt(key, BigDecimalUtil.getString(coverAmount));
            String flowAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(flowAmount));
            String walletAmountMoneyStr = DESHelperUtil.encrypt(key, BigDecimalUtil.getString(walletAmount));
            wallet.setProfitAmount(profitAmountMoneyStr);
            wallet.setRewardAmount(rewardAmountMoneyStr);
            wallet.setCoverAmount(coverAmountMoneyStr);
            wallet.setFlowAmount(flowAmountMoneyStr);
            wallet.setWalletAmount(walletAmountMoneyStr);
            wallet.setSecretKey(key);
            // 保存钱包信息
            walletService.saveOrUpdate(wallet);
        }
        this.with(merchant1,cashoutRecords);

    }


    public static void main(String[] args) {
        // 签约
//        UserSign userSign = new UserSign();
//        userSign.setRealName("田振丰");
//        userSign.setCardId("220722199203191010");
//        userSign.setPhoneNo("16643588008");
//        Map<String, Object> map = HqyApiUtilsV2.callHqyMerApi(UUID.randomUUID().toString(),
//                HqyMerFunctionEnumsV2.USER_SIGN.getCode(),
//                HqyApiContantsV2.HQY_MER_ID_DQHB_V2,
//                userSign);
//        System.out.println(map.get("result"));
//        JSONObject jsonObject =JSONObject.parseObject(map.get("result").toString());
//        System.out.println(jsonObject.get("businessStatus"));
//        System.out.println(jsonObject.get("explain"));
          //多商户余额查询
//        SearchMer req = new SearchMer();
//        req.setJnlNo("155485631549635");
//        Map<String, Object> map = HqyApiUtilsV2.callHqyMerApi(
//                UUID.randomUUID().toString(),
//                HqyMerFunctionEnumsV2.SEARCH_MER.getCode(),
//                req);
//        System.out.println(map.get("result").toString());
        // 批量出款
//        BatchPayment req = new BatchPayment();
//        req.setBatchNo(UUID.randomUUID().toString());
//        req.setPathNo("2020092720451157884");
//        req.setTotalAmount("100.53");
//        req.setTotalNum("1");
//        //李玉菡 130125199904158541 6230580000295895291 17331221790
////       李杨 142330199511123116 6226200110389328 17610390757
//        List<BatchPaymentList> list = new ArrayList<>();
//        BatchPaymentList order = new BatchPaymentList();
//        order.setOrderId(IdGen.uuid());
//        order.setCardId("130125199904158541");
//        order.setCardNo("6230580000295895291");
//        order.setPayAmount("100.53");
//        order.setPhoneNo("17331221790");
//        order.setRealName("李玉菡");
//        list.add(order);
//        req.setPayInfos(list);
//        Map<String, Object> hqyResultMap = HqyApiUtilsV2.callHqyMerApi(UUID.randomUUID().toString(), HqyMerFunctionEnumsV2.BATCH_PAYMENT.getCode(), req);
//        System.out.println(hqyResultMap);

        //单笔查询
        QueryPayment req = new QueryPayment();
        req.setBatchNo("cc15d53b-132b-41b8-9b58-122220bcacda");
        req.setOrderId("d746324e890c437cb87b19266034cb61");
        Map<String, Object> hqyResultMap = HqyApiUtilsV2.callHqyMerApi(
                UUID.randomUUID().toString(),
                HqyMerFunctionEnumsV2.QUERY_PAYMENT.getCode(),
                req,null);
        System.out.println("hqyResultMap->{}"+ hqyResultMap);
        System.out.println(hqyResultMap.get("result").toString());
        System.out.println(hqyResultMap.get("result"));
        JSONObject obj =JSONObject.parseObject(hqyResultMap.get("result").toString());
        System.out.println(obj.get("resultCode").toString());

    }



}
